package com.hit.core.context.constant;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import com.hit.core.consts.CommonConstant;
import com.hit.core.consts.SymbolConstant;
import com.hit.core.exception.ServiceException;
import com.hit.core.pojo.cryptogram.CryptogramConfigs;

import java.util.List;

import static com.hit.core.exception.enums.ServerExceptionEnum.CONSTANT_EMPTY;

public class ConstantContextHolder {
    private static final Log log = Log.get();

    /**
     * 获取放开xss过滤的接口
     */
    public static List<String> getUnXssFilterUrl() {
        String snowyUnXssFilterUrl = getSysConfigWithDefault("UN_XSS_FILTER_URL", String.class, null);
        if (ObjectUtil.isEmpty(snowyUnXssFilterUrl)) {
            return CollectionUtil.newArrayList();
        } else {
            return CollectionUtil.toList(snowyUnXssFilterUrl.split(SymbolConstant.COMMA));
        }
    }

    /**
     * 获取jwt密钥，默认是32位随机字符串
     */
    public static String getJwtSecret() {
        return getSysConfigWithDefault("JWT_SECRET", String.class, RandomUtil.randomString(32));
    }

    /**
     * 获取默认密码
     */
    public static String getDefaultPassWord() {
        return getSysConfigWithDefault("DEFAULT_PASSWORD", String.class, CommonConstant.DEFAULT_PASSWORD);
    }

    /**
     * 获取会话过期时间，默认2小时
     */
    public static Long getSessionTokenExpireSec() {
        return getSysConfigWithDefault("SESSION_EXPIRE", Long.class, 2 * 60 * 60L);
    }

    /**
     * 获取token过期时间（单位：秒）
     * <p>
     * 默认时间1天
     */
    public static Long getTokenExpireSec() {
        return getSysConfigWithDefault("TOKEN_EXPIRE", Long.class, 86400L);
    }

    /**
     * 获取自定义的windows环境本地文件上传路径
     */
    public static String getDefaultFileUploadPathForWindows() {
        return getSysConfigWithDefault("FILE_UPLOAD_PATH_FOR_WINDOWS", String.class, "");
    }

    /**
     * 获取自定义的linux环境本地文件上传路径
     */
    public static String getDefaultFileUploadPathForLinux() {
        return getSysConfigWithDefault("FILE_UPLOAD_PATH_FOR_LINUX", String.class, "");
    }

    /**
     * 获取是否允许单用户登陆的开关， 默认为false
     */
    public static Boolean getEnableSingleLogin() {
        return getSysConfigWithDefault("ENABLE_SINGLE_LOGIN", Boolean.class, false);
    }

    /**
     * 获取config表中的配置，如果为空返回默认值
     *
     * @param configCode   变量名称，对应sys_config表中的code
     * @param clazz        返回变量值的类型
     * @param defaultValue 如果结果为空返回此默认值
     */
    public static <T> T getSysConfigWithDefault(String configCode, Class<T> clazz, T defaultValue) {
        String configValue = ConstantContext.me().getStr(configCode);
        if (ObjectUtil.isEmpty(configValue)) {
            // 将默认值加入到缓存常量
            log.warn(">>> 系统配置sys_config表中存在空项，configCode为：{}，系统采用默认值：{}", configCode, defaultValue);
            ConstantContext.me().put(configCode, defaultValue);
            return defaultValue;
        } else {
            try {
                return Convert.convert(clazz, configValue);
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

    /**
     * 获取config表中的配置，如果为空，是否抛出异常
     *
     * @param configCode   变量名称，对应sys_config表中的code
     * @param clazz        返回变量值的类型
     * @param nullThrowExp 若为空是否抛出异常
     */
    public static <T> T getSysConfig(String configCode, Class<T> clazz, Boolean nullThrowExp) {
        String configValue = ConstantContext.me().getStr(configCode);
        if (ObjectUtil.isEmpty(configValue)) {
            if (nullThrowExp) {
                String format = StrUtil.format(">>> 系统配置sys_config表中存在空项，configCode为：{}", configCode);
                log.error(format);
                throw new ServiceException(CONSTANT_EMPTY.getCode(), format);
            } else {
                return null;
            }
        } else {
            try {
                return Convert.convert(clazz, configValue);
            } catch (Exception e) {
                if (nullThrowExp) {
                    String format = StrUtil.format(">>> 系统配置sys_config表中存在格式错误的值，configCode={}，configValue={}", configCode, configValue);
                    log.error(format);
                    throw new ServiceException(CONSTANT_EMPTY.getCode(), format);
                } else {
                    return null;
                }
            }
        }
    }


    /**
     * 获取加解密的配置
     */
    public static CryptogramConfigs getCryptogramConfigs() {
        boolean snowyTokenEncDec = getSysConfigWithDefault("TOKEN_ENCRYPTION_OPEN", Boolean.class, true);
        boolean snowyVisLogEnc = getSysConfigWithDefault("VISLOG_ENCRYPTION_OPEN", Boolean.class, true);
        boolean snowyOpLogEnc = getSysConfigWithDefault("OPLOG_ENCRYPTION_OPEN", Boolean.class, true);
        boolean snowyFieldEncDec = getSysConfigWithDefault("FIELD_ENC_DEC_OPEN", Boolean.class, true);

        CryptogramConfigs cryptogramConfigs = new CryptogramConfigs();
        cryptogramConfigs.setTokenEncDec(snowyTokenEncDec);
        cryptogramConfigs.setVisLogEnc(snowyVisLogEnc);
        cryptogramConfigs.setOpLogEnc(snowyOpLogEnc);
        cryptogramConfigs.setFieldEncDec(snowyFieldEncDec);
        return cryptogramConfigs;
    }


}
